<template>
  <div>
    <div id="ui_top_panel" class="top_panel">
      <!-- 导航栏 -->
      <div class="navbar">
        <!--        <ul>-->
        <!--          <li class="dropdown"><a title="图像" class="drop_menu_item">图像 &#9662;</a>-->
        <!--            <div class="dropdown-content">-->
        <!--              <a title="从本地磁盘载入或添加图像" @click="getResource">载入/添加图像</a>-->
        <!--            </div>-->
        <!--          </li>-->
        <!--        </ul>-->
        <el-dialog
          v-dialogDrag
          title="选择文件"
          :visible.sync="centerDialogVisible"
          width="50%"
          :modal="false"
          center
        >
          <!-- <span>需要注意的是内容是默认不居中的</span>
          <span slot="footer" class="dialog-footer"> -->
          <div>
            <el-button icon="el-icon-back" class="btnClass" circle @click="getBack"/>
            <el-input
              v-model="selectpath"
              style="width: 400px;"
              class="filter-item"
              placeholder="请输入路径"
              @keydown.enter.native="selectFiles"
            />
            <el-button icon="el-icon-search" class="btnClass" circle @click="selectFiles"/>
          </div>
          <div class="explorerBox">
            <jason-vue-explorer
              mode="normal"
              :data-arr="dataArr"
              :selected-arr.sync="selectedArr"
              :other-column-arr="otherColumnArr"
              @clickFolder="clickFolder"
              @clickFile="clickFile"
              @dblclickFolder="dblclickFolder"
              @dblclickFile="dblclickFile"
            />
            <!-- <jason-vue-explorer
              mode="normal"
              :data-arr="dataArr"
              :selected-arr.sync="selectedArr"
              @clickFolder="clickFolder"
              @clickFile="clickFile"
              @dblclickFolder="dblclickFolder"
              @dblclickFile="dblclickFile"
              @close='closeDialog'/> -->
            <!-- @update:selectedArr="updateSelectedArr" @dragMove="dragMove"-->
          </div>
          <!-- :action-arr="actionArr" -->
          <span slot="footer" class="dialog-footer">
            <el-button @click="closeDialog">取 消</el-button>
            <el-button type="primary" @click="sumbitData">确 定</el-button>
          </span>
        </el-dialog>
      </div>
      <div class="toolbar">
        <ul>
          <li>
            <toggle-button
              v-model="isVetical"
              :width="60"
              :height="30"
              :disabled=true
              :sync="true"
              :labels="{checked: '纵向', unchecked: '横向'}"
              @change="changeVetical"
            />
          </li>
          <li id="toolbar_zoom_out" style="margin-left: 2em;" title="缩小" @click="zoom_out()">&minus;</li>
          <li id="toolbar_zoom_in" title="放大" @click="zoom_in()">&plus;</li>
          <li>
            <el-input-number v-model="num_degree" @change="handleDegreeChange" :precision="1"
                             :step="0.5" :min="-89" :max="89" label="旋转角" step-strictly
                             size="small" :disabled="!can_change_degree">
            </el-input-number>
          </li>
          <li id="passImage" style="margin-left: 2em;" title="审核通过" @click="passImage()">审核通过</li>
          <li id="noPassImage" title="审核不通过" @click="noPassImage()">审核不通过</li>
          <li id="judgeTask" style="margin-left: 20em;" title="任务通过" @click="passJudgeTask(1)">任务通过</li>
          <li id="noJudgeTask" title="任务不通过" @click="passJudgeTask(0)">任务退回</li>
          <li id="go_back" @click="go_back()" title="返回">返回</li>
        </ul>
      </div> <!-- endof #toolbar -->
      <input id="invisible_file_input" type="file" multiple name="files[]" style="display:none">
    </div> <!-- endof #top_panel -->
    <!-- 中部：包括左侧工具栏和图像显示区 左边框250 -->
    <div class="middle_panel">
      <div id="leftsidebar" class="leftSizeBar" style="height: 100%;">
        <div>
          <el-card class="cardClass">
            <div>
              <div slot="header" class="clearfix">
                <span>图片列表</span>
              </div>

              <div class="box">
                <div v-for="(img, index) in image_info_list" :key="index" @click="show_remote_image(index)">
                  <el-button type="text" :class="{active: currentIndex === index}" style="padding:0;"
                             :title="img.name.imageName">
                    {{ '(' + (index + 1) + ')' }}.{{ taskStatus[img.name.status] }}_{{ img.name.imageName }}
                  </el-button>
                </div>
              </div>
            </div>
          </el-card>
        </div>
        <div id="leftAll" style="height: 100%">
          <el-card class="box-card">
            <div id="leftTree" slot="header" style="height: 100%" class="clearfix">
              <span>目录树</span>
            </div>
            <div id="Tree" class="tree_box">
              <el-tree
                ref="vuetree"
                :data="node_data"
                node-key="id"
                highlight-current
                default-expand-all
                :expand-on-click-node="false"
              >
                <span
                  slot-scope="{ node, data }"
                  style="width: 100%"
                  class="custom-tree-node"
                  @click="() => show_node(node, data)"
                >
                  <span :style="getDetectStyle(node.data.need_detect)">
                    {{ node.label }}  {{ node.data.label_idx }}
                  </span>
                </span>
              </el-tree>
            </div>
          </el-card>
        </div>
      </div> <!-- end of leftsidebar -->
      <!-- 主显示区：图像画布canvas -->
      <!--      <div id = "leftSidearHidden" display:none></div>-->
      <div id="display_area" v-loading="is_loading_current_image">
        <div id="canvas_panel" @mousewheel.prevent="handleWheel">
          <VueDragResize
            ref="vueDR"
            :is-resizable="false"
            :is-draggable="isDragActive&&image_info_list.length!==0"
            :w="1"
            :h="1"
            @dragging="onDragging"
          >
            <canvas id="image_canvas" class="mainSizeBar" :style="{cursor: 'pointer'}"/>
            <canvas id="region_canvas" class="mainSizeBar" :style="getStyle()"/>
          </VueDragResize>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import jasonVueExplorer from './explorer'
import { getFiles, getBase64, getImageInfo } from '../../../api/commonService'
import VueDragResize from 'vue-drag-resize'
import { passJudge, passJudgeTask } from '@/api/task/taskcheck'

class ImageMetadata {
  constructor(fileref, filename, size, fileid, result_path) {
    this.fileid = fileid
    this.filename = filename
    this.size = size
    this.result_path = result_path
    this.isVetical = true
    this.fileref = fileref // image url or local file ref.图片的详细信息
    this.regions = [] // 区域
    this.base64_img_data = '' // image data stored as base 64
    this.node_tree = [] // 目录树
  }
}

class ImageRegion {
  constructor() {
    this.node_id = 0 // 记录其在目录树节点的id
    this.is_user_selected = false // 默认为不选中
    this.shape_attributes = new Map() // 存该区域的坐标
  }
}

export default {
  name: 'MarkingCheck',
  components: {
    jasonVueExplorer,
    VueDragResize
  },
  data() {
    return {
      checkAll: false,
      selectedImages: [],
      isIndeterminate: true,
      num_degree: 0,  //当前框的旋转角
      can_change_degree: false,
      statusOrder: {
        0: 1, //审核不通过排在第二
        1: 3, //未完成排在第四
        2: 2, //完成部分排在第三
        3: 0, //等待审核排在最前面
        4: 4, //审核通过排在最后
        5: 2  //完成部分第三
      },
      taskStatus: ['审核不通过', '未完成', '完成部分', '等待审核', '审核通过', '完成部分'], //0审核不通过/1未完成/2完成部分/3等待审核/4审核通过
      result_path: '',
      index: '',
      imageIdList: [],
      markTaskId: 0,
      imageId: 0,
      leftTree: '',
      leftAll: '',
      tree: '',
      isDialogOpen: false,
      isDragActive: true,
      // selectpath: 'D:\\',
      selectpath: '/home/fzuir/newspaper_data',
      rootPath: '/home/fzuir/newspaper_data',
// 远程文件管理需要的变量
      currentIndex: -1,
      centerDialogVisible: false,
      // rootPath: 'D:\\',
      currentPath: '',
      pathStack: [],
      dataArr: [],
      selection: true,
      selectedArr: [],
      otherColumnArr: [
        {
          label: '时间',
          key: 'time'
        }
      ],
      seletedFileList: [],
      // imageDetailList:[], //存储被选中图片的所有信息 根据seletedFileList中的信息做扩展 base64 width height  size
      isVetical: true,
      nid: 0, // 目录树的id
      node_data: [],
      current_node: {},
      current_parent_node: {},
      can_draw_region: false, // 是否能画图
      REGION_SHAPE: { // 标注区域的形状
        RECT: 'rect' // 矩形
      },
      REGION_EDGE_TOL: 5, // pixel，误差范围之内就算点击到框边缘
      REGION_CONTROL_POINT_SIZE: 2,
      REGION_POINT_RADIUS: 3,
      POLYGON_VERTEX_MATCH_TOL: 5,
      REGION_MIN_DIM: 3, // 如果画的框太小
      MOUSE_CLICK_TOL: 2, // 移动超过2px就算移动
      CANVAS_DEFAULT_ZOOM_LEVEL_INDEX: 3, // 指代1
      CANVAS_ZOOM_LEVELS: [0.25, 0.5, 0.75, 1.0, 1.125, 1.25, 1.375, 1.5, 1.625, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.5, 4, 4.5, 5], // 缩放的尺度

      THEME_REGION_BOUNDARY_WIDTH: 2,
      THEME_BOUNDARY_LINE_COLOR: '#1a1a1a',
      THEME_BOUNDARY_FILL_COLOR: '#ff0000',
      THEME_SEL_REGION_FILL_COLOR: '#a2a8a2',
      THEME_SEL_REGION_FILL_BOUNDARY_COLOR: '#000000',
      THEME_SEL_REGION_OPACITY: 0.5,
      THEME_CONTROL_POINT_COLOR: '#ff0000',

      img_metadata: {}, // 用来存已导入的每张图片的详细信息，包括上面标注的区域信息data structure to store loaded images metadata
      img_count: 0, // count of the loaded images
      canvas_regions: [], // 当前图片窗口中canvas的坐标 image regions spec. in canvas space
      canvas_scale: 1.0, // 原图缩小到canvas的倍数 current scale of canvas image

      image_id_list: [], // array of image id (in original order)
      image_name_list: [], // 保存已加载图片的image_name
      image_path_list: [],
      image_info_list: [], //{id,name:{imageName,status},path}
      image_id: '', // id:{filename+length} of current image
      image_index: -1, // 当前正在浏览的图片索引index

      current_image_filename: '',
      current_image: '',
      current_image_width: 0,
      current_image_height: 0,

      // image canvas
      img_canvas: '',
      img_ctx: '',
      reg_canvas: '',
      reg_ctx: '',
      canvas_width: 0,
      canvas_height: 0,

      // canvas zoom
      canvas_zoom_level_index: 3, // 1.0
      canvas_scale_without_zoom: 1.0,

      // state of the application
      is_user_drawing_region: false,
      current_image_loaded: false, // 图片是否在加载中
      is_window_resized: false,
      is_user_resizing_region: false,
      is_user_moving_region: false,
      is_user_drawing_polygon: false,
      is_region_selected: false,
      is_all_region_selected: false,
      is_user_updating_attribute_name: false,
      is_user_updating_attribute_value: false,
      is_user_adding_attribute_name: false,
      is_canvas_zoomed: false,
      is_loading_current_image: false, // 是否正在加载图片(导入图片的时候会用)
      is_region_boundary_visible: true,

      // region
      current_shape: '',
      user_sel_region_id: -1,
      click_x0: 0,
      click_y0: 0,
      click_x1: 0,
      click_y1: 0,
      region_click_x: 0,
      region_click_y: 0,
      region_edge: [-1, -1],
      current_x: 0,
      current_y: 0,

      // UI html elements
      ui_top_panel: '',
      canvas_panel: '',

      BBOX_LINE_WIDTH: 4,
      BBOX_SELECTED_OPACITY: 0.3,
      BBOX_BOUNDARY_FILL_COLOR_ANNOTATED: '#f2f2f2',
      BBOX_BOUNDARY_FILL_COLOR_NEW: '#aaeeff',
      BBOX_BOUNDARY_LINE_COLOR: '#1a1a1a',
      BBOX_SELECTED_FILL_COLOR: '#ffffff',

      is_ctrl_pressed: false,
      remote_node_data: [], // 从后端获取的当前图片的node_data
      remote_is_vetical: true, // 从后端获取的当前图片的状态
      remote_regions: [], // 远程node中读出的region
      max_id: 0 // 远程的最大id
    }
  },

  activated() {
    if (this.$store.state.taskcheck.flag === true && this.$route.query.taskMarkId !== this.$store.state.taskcheck.task_id) {
      console.log('清空')
      Object.assign(this.$data, this.$options.data.call(this))
      this.get_init()
      this.$store.commit('SET_FLAG_FALSE')
      this.$store.commit('SET_TASKID', this.$route.query.taskMarkId)
      // this.clear_reg_canvas()
    }
    this.getCheckedImage() // 获取图片和对应json文件
  },
  created() {
    // console.log("1111111")
  },
  mounted() {
    // console.log(this.$store.state.marking.flag)
    this.get_init()
    const that = this
    // window.addEventListener('keydown', this.keydown)
    // user clicks on the canvas
    this.reg_canvas.addEventListener('mousedown', function(e) {
      that.click_x0 = e.offsetX // 相对于region_canvas的坐标
      that.click_y0 = e.offsetY
      // console.log('鼠标按下:', that.click_x0, that.click_y0)
      that.region_edge = that.is_on_region_corner(that.click_x0, that.click_y0) // 点击到框的四角上
      const region_id = that.is_inside_region(that.click_x0, that.click_y0)
      // 如果鼠标按到了已经选中的区域，可以移动或者调整区域大小
      // 如果按到了没有选中的区域或者本身没有区域被选中，则判定为在画框
      if (region_id === -1) { // 点击到别的区域，判定为在画框
        // unselect all regions
        that.is_region_selected = false
        that.toggle_all_regions_selection(false)
        that.redraw_reg_canvas()
      }
      e.preventDefault()
    }, false)
    // // implements the following functionalities:
    // //  - new region drawing (including polygon)
    // //  - moving/resizing/select/unselect existing region
    this.reg_canvas.addEventListener('mouseup', function(e) {
      that.click_x1 = e.offsetX
      that.click_y1 = e.offsetY
      // console.log('鼠标抬起', that.click_x1, that.click_y1)
      const click_dx = Math.abs(that.click_x1 - that.click_x0) // 移动的距离
      const click_dy = Math.abs(that.click_y1 - that.click_y0)
      // denotes a single click (= mouse down + mouse up)单击一个区域，即选中,记录选中区域的id，并且将对应的isselect标记为true
      if (click_dx < that.MOUSE_CLICK_TOL || click_dy < that.MOUSE_CLICK_TOL) {
        // console.log('鼠标按下移动距离过短，判定为单击')
        const region_id = that.is_inside_region(that.click_x0, that.click_y0)
        if (region_id >= 0) {
          // first click selects region
          // console.log('选中框id：', region_id)
          that.user_sel_region_id = region_id
          that.is_region_selected = true
          that.is_user_moving_region = false
          that.is_user_drawing_region = false
          that.can_draw_region = false
          that.num_degree = that.canvas_regions[region_id].shape_attributes.get('degree')  //读取角度
          // 将目录树的节点设置为高亮状态
          const select_node_id = that.canvas_regions[region_id].node_id
          // console.log('选中框的region_id：', select_node_id)
          that.$refs['vuetree'].setCurrentKey()
          that.$refs['vuetree'].setCurrentKey(select_node_id)
          that.selectCamera(select_node_id)
          // de-select all other regions if the user has not pressed Shift
          if (!e.shiftKey) {
            that.toggle_all_regions_selection(false)
          }
          that.set_region_select_state(region_id, true)
          // show_message('Click and drag to move or resize the selected region');
        } else {
          console.log('没有框被选中,取消所有框的选择状态')
          that.is_region_selected = false
          that.use_sel_region_id = -1
          that.$refs['vuetree'].setCurrentKey()  //清空目录树的选中状态
          that.toggle_all_regions_selection(false)
          if (that.is_user_drawing_region) {  //如果没有区域被选中，鼠标按下移动的距离又很小，则全部设置为未选中
            // clear all region selection
            that.is_user_drawing_region = false
          }
        }
        // console.log('取消画框')
        that.redraw_reg_canvas()
        that.reg_canvas.focus()
      }
    })
  },
  deactivated() {
    console.log('deactivated')
    window.removeEventListener('keydown', this.keydown)
  },
  methods: {
    selectCamera(select_node_id) {

        //这次选中的节点
        let currentNode = this.$refs.vuetree.getNode(select_node_id)
        console.log(currentNode)
        let openNode = currentNode
        let sum = 0
        while(openNode.parent !== null)
        {
          openNode.parent.expanded = true
          openNode = openNode.parent
        }
        //同级
        let all = 0

        let count1 = currentNode.data.label_idx
        // console.log("同级", count1)

        if(currentNode.parent.parent.parent === null)
        {

        } else {
          currentNode = currentNode.parent
          all = all + count1
        }

        let num = 0
        let num1 = 0
        let label = currentNode.parent.data.label
        let index = currentNode.parent.data.label_idx
        // console.log(label,index)

        let Node = currentNode.parent.parent
        // console.log("第二级")
        // console.log("最顶级",Node)
        let flag = 0
        let beforeCount = 0
        let currentCount = 0
        for (let i = 0; i < Node.childNodes.length; i++)
        {

          if(Node.childNodes[i].data.label === label && Node.childNodes[i].data.label_idx === index )
          {
            beforeCount = beforeCount + flag
            // console.log("beforeCount",beforeCount)
            let label1 = currentNode.data.label
            let index1 = currentNode.data.label_idx
            let Node3 = Node.childNodes[i]
            for (let i = 0;i<Node3.childNodes.length;i++)
            {
              if(Node3.childNodes[i].data.label === label1 && Node3.childNodes[i].data.label_idx === index1)
              {
                currentCount = currentCount + i
                // console.log("currentCount",currentCount)
                break;
              }
              else{
                let Node1 =  Node3.childNodes[i]
                // console.log("222Node1",Node1)
                if(Node1.expanded === false){
                }
                else {
                  let sum = 0
                  for(let i=0; i<Node1.childNodes.length;i++)
                  {
                    let Node2 = Node1.childNodes[i]
                    if(Node2.expanded === true )
                    {
                      sum = sum + Node2.childNodes.length + 1
                      // console.log("2if",sum)
                    }
                    else
                    {
                      sum = sum + 1
                      // console.log("2else",sum)
                    }
                  }
                  num1 = num1 + sum
                  // console.log("2sum",sum)
                }
                currentCount = num1
                // console.log("2num",num1)
              }
            }
            break;
          }
          else {

            let Node1 =  Node.childNodes[i]
            if(Node1.expanded === false){
              num = num + 1
            }
            else {
              let sum = 0
              for(let i=0; i<Node1.childNodes.length;i++)
              {
                let Node2 = Node1.childNodes[i]
                if(Node2.expanded === true )
                {
                  sum = sum + Node2.childNodes.length + 1
                  console.log("Node2 sum",sum)
                }
                else
                {
                  sum = sum + 1
                  console.log("Node2 sum",sum)
                }
                console.log("else 内",sum)
              }
              num = num + sum
            }
            beforeCount = num
            console.log("num",num)


            // console.log("Node1",Node1)
          }
          flag = i + 1
          // console.log("index1",flag)
        }
          all = all + beforeCount + currentCount + 1
          // console.log("all",all)
          let dom = document.querySelector("#Tree")
          let dom1 = document.querySelector("#Tree1")
          //一个节点的高度是26px,这个值能否从对象中获取，等我把这个功能做好再考虑吧
          let nodeHight = 26
          // dom1.style.height = (all * nodeHight) + "px"
          // 13是因为，div高度为700像素，nodeHight*27=702，略超过700，
          // 又因为，div高度是700像素，要使被选中的节点显示在div可视区域的中间，
          // 所以就要将27折半，后一半节点要参与滚动条的位移
          // 计算位移距离时，减350的原因也是一样，要使被选中的节点显示在div可视区域的中间，就要减去div高度的一半
          if (9 < all) {
              dom.scrollTo(0, (all * nodeHight) - 100)
          } else {
              dom.scrollTo(0, 0)
          }
    },
    handleCheckAllChange(val) {
      let all = []
      for (let i = 0; i < this.image_info_list.length; i++) {
        all.push(i)
      }
      console.log(all)
      this.selectedImages = val ? all : []
      this.isIndeterminate = false
    },
    handleSelectedImagesChange(value) {
      console.log(value)
      let checkedCount = value.length
      this.checkAll = checkedCount === this.image_info_list.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.image_info_list.length
    },
    getCheckedImage() {
      this.onDragging({ top: 0, left: 0 })
      this.dataArr = []
      let imageList = this.$route.query.row
      this.markTaskId = this.$route.query.taskMarkId

      for (const item of imageList) {
        // console.log(item)
        const data_item = {}
        data_item['key'] = item.imageId
        data_item['name'] = item.imageName
        data_item['filepath'] = item.iamgePath
        data_item['status'] = item.status
        data_item['type'] = 'image'
        data_item['result_path'] = item.resultPath
        if (item.type === 'image') {
          data_item['height'] = item.height
          data_item['size'] = item.size
          data_item['width'] = item.width
          // data_item['base64'] = item.base64
        }
        this.seletedFileList.push(data_item)
      }
      this.store_remote_img_ref()
      window.addEventListener('keydown', this.keydown)
    },
    compare(obj1, obj2) {
      let s1 = obj1.status
      let s2 = obj2.status
      if (s1 < s2) {
        return -1
      } else if (s1 > s2) {
        return 1
      } else {
        return 0
      }
    },
    passImage() {
      // 可以用selectedImages进行操作
      this.$confirm('是否确定通过该图片的审核?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let data = {} // 要用对象，不能用数组
        data['pass'] = 1
        data['imageId'] = this.image_info_list[this.currentIndex].id
        data['markTaskId'] = this.markTaskId
        passJudge(data).then(res => {
          this.$message({
            message: '审核通过 成功',
            type: 'success'
          })
          this.image_info_list[this.currentIndex].name.status = 4  //审核通过
          this.image_info_list.sort(this.compare_image) //重新排序
          //查找重新排序后当前的图片位置在哪
          let sorted_image_index = -1
          for (let i = 0; i < this.image_info_list.length; i++) {
            if (this.image_info_list[i].id === this.image_id) {
              sorted_image_index = i
              break
            }
          }
          //如果重新排序后图片的位置比原位置靠前，那就显示下一张；如果是靠后的话，currentIndex不变，就会显示下一张
          if (sorted_image_index <= this.currentIndex) {
            if (this.currentIndex + 1 < this.image_info_list.length) {  //防止越界
              this.show_remote_image(this.currentIndex + 1)
            }
          } else {
            this.show_remote_image(this.currentIndex)
          }
        }).catch((res) => {
          this.$message({
            message: '审核通过 失败',
            type: 'error'
          })
          throw res
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消'
        })
      })
    },
    noPassImage() {
      this.$confirm('是否确定不通过该图片的审核?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let data = {}
        data['pass'] = 0
        data['imageId'] = this.image_info_list[this.currentIndex].id
        data['markTaskId'] = this.markTaskId
        passJudge(data).then(res => {
          this.$message({
            message: '审核不通过 成功',
            type: 'success'
          })
          this.image_info_list[this.currentIndex].name.status = 0
          this.image_info_list.sort(this.compare_image) //重新排序
          //查找重新排序后当前的图片位置在哪
          let sorted_image_index = -1
          for (let i = 0; i < this.image_info_list.length; i++) {
            if (this.image_info_list[i].id === this.image_id) {
              sorted_image_index = i
              break
            }
          }
          //如果重新排序后图片的位置比原位置靠前，那就显示下一张；如果是靠后的话，currentIndex不变，就会显示下一张
          if (sorted_image_index <= this.currentIndex) {
            this.show_remote_image(this.currentIndex + 1)
          } else {
            this.show_remote_image(this.currentIndex)
          }
        }).catch((res) => {
          this.$message({
            message: '审核不通过 失败',
            type: 'error'
          })
          throw res
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消'
        })
      })
    },
    passJudgeTask(pass) {
      let message = pass === 1 ? '是否确定通过整个任务的审核?' : '是否确定退回个任务的审核?'
      this.$confirm(message, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let data = {}
        data['pass'] = pass   // 1表示任务通过,0不通过
        data['markTaskId'] = this.markTaskId
        let status = pass === 1 ? 4 : 0
        passJudgeTask(data).then(res => {
          for (let i = 0; i < this.image_info_list.length; i++) {
            this.image_info_list[i].name.status = status
          }
          this.$message({
            message: '操作成功',
            type: 'success'
          })
        }).catch((res) => {
          this.$message({
            message: '操作失败',
            type: 'error'
          })
          throw res
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消'
        })
      })
    },
    keydown(e) {
      // if (e.which === 46 || e.which === 8) { // Del or Backspace
      //   if (!this.isDialogOpen) {
      //     // console.log('按下del')
      //     this.del_sel_regions()
      //     e.preventDefault() // 阻止默认事件，因为会导致搜索框不能删除文字，所以不阻止删除的冒泡时间
      //     return
      //   }
      // }
      // // Ctrl + 快捷键
      // if (e.ctrlKey) {
      //   this.is_ctrl_pressed = true
      //   if (e.which === 83) { // Ctrl + s
      //     this.save_data()
      //     e.preventDefault()
      //     return
      //   }
      // }
    },
    reposition() {
      this.reset_zoom_level()
      this.onDragging({ top: 0, left: 0 })
    },
    handleDegreeChange(value) {
      console.log('旋转角', value)
      const current_region = this.img_metadata[this.image_id].regions[this.user_sel_region_id]//用户选择的区域
      let image_attr = current_region.shape_attributes //真实的坐标
      let canvas_attr = this.canvas_regions[this.user_sel_region_id].shape_attributes //在canvas中的坐标
      let current_node_info = this.$refs['vuetree'].getNode(current_region.node_id)//当前选择区域的目录树node信息
      // console.log('当前区域对应的目录树节点的信息：', current_node_info)
      switch (canvas_attr.get('name')) {
        case this.REGION_SHAPE.RECT:
          image_attr.set('degree', value)
          canvas_attr.set('degree', value)
          current_node_info.data.degree = value
          this.hasModified = true
          this.redraw_reg_canvas()
          this.reg_canvas.focus()
          break
      }
    },
    onDragging(newRect) {
      // this.$refs.vueDR.parentWidth = 1283
      // // this.$refs.vueDR.parentWidth = 0
      // this.$refs.vueDR.right = 1282
      // this.$refs.vueDR.Height = 0
      // this.$refs.vueDR.bottom = -1
      // console.log('width',this.$refs.vueDR.parentWidth - newRect.left - this.$refs.vueDR.right)
      // console.log('height',this.parentHeight - newRect.top - this.$refs.vueDR.bottom)
      // console.log('newRect',newRect)
      this.$refs.vueDR.top = newRect.top
      this.$refs.vueDR.left = newRect.left
    },
    throttle(fn, gapTime) {
      const _this = this
      return function() {
        const _nowTime = +new Date()
        if (_nowTime - _this._lastTime > gapTime || !_this._lastTime) {
          fn(...arguments)// 函数可以带参数
          _this._lastTime = _nowTime
        }
      }
    },
    handleWheel(e) {
      e.stopPropagation()
      this.throttle(this.pageUpOrDown, 100)(e)
    },
    pageUpOrDown(e) {
      if (e.deltaY > 0) {
        // 向下
        // this.clickNext()//执行的事件逻辑。比如向下翻页
        this.zoom_out()
      } else if (e.deltaY < 0) {
        // 向上
        this.zoom_in()// 比如向上翻页
      }
    },
    getStyle() {
      if (this.isDragActive && this.image_info_list.length !== 0) {
        // console.log("111111111111")
        return { cursor: 'pointer' }
      } else {
        return {}
      }
    },
    getDetectStyle(need_detect) {
      // console.log('2222222222222',need_detect)
      if (need_detect === 0) {
        return { width: '100%', color: 'blue' }
      } else {
        return { width: '100%' }
      }
    },
    /*
    初始化
    * */
    get_init() {
      this.invisible_file_input = document.getElementById('invisible_file_input')
      this.img_canvas = document.getElementById('image_canvas')
      this.img_ctx = this.img_canvas.getContext('2d')
      this.reg_canvas = document.getElementById('region_canvas')
      this.leftAll = document.getElementById('leftAll')
      this.leftTree = document.getElementById('leftTree')
      this.tree = document.getElementById('Tree')
      // console.log('leftAll.style.offsetHeight',this.leftAll.offsetHeight)
      // console.log('leftTree.style.offsetHeight',this.leftTree.offsetHeight)
      // console.log('tree.style.offsetHeight',this.tree.offsetHeight)
      this.reg_ctx = this.reg_canvas.getContext('2d')
      this.ui_top_panel = document.getElementById('ui_top_panel')
      this.canvas_panel = document.getElementById('canvas_panel') // 包裹image_canvas和region_canvas的区域
      this.canvas_zoom_level_index = this.CANVAS_DEFAULT_ZOOM_LEVEL_INDEX
      this.current_shape = this.REGION_SHAPE.RECT
    },
    /*
    目录树部分
    * */
    show_node(node, data) {
      // console.log('点击')
      // console.log('node', node)  //level只是层级 1-3 parent是父节点
      const current_node_id = node.data.id
      for (let i = 0; i < this.canvas_regions.length; i++) {
        if (this.canvas_regions[i].node_id === current_node_id) {
          // console.log('找到对应的区域', this.canvas_regions[i])
          this.toggle_all_regions_selection(false)
          this.set_region_select_state(i, true)
          this.redraw_reg_canvas()
          this.reg_canvas.focus()
          break
        }
      }
    },
    get_image_id(filename, size) {
      if (typeof (size) === 'undefined') {
        return filename
      } else {
        return filename + size
      }
    },
    set_all_canvas_scale(s) {
      this.img_ctx.scale(s, s) // 只缩放以后的画图操作，会同时缩放坐标
      this.reg_ctx.scale(s, s)
    },
    set_all_canvas_size(w, h) {
      this.img_canvas.height = h
      this.img_canvas.width = w
      this.reg_canvas.height = h
      this.reg_canvas.width = w
      this.canvas_panel.style.height = h + 'px'
      this.canvas_panel.style.width = w + 'px'
    },
    // transform regions in image space to canvas space
    load_canvas_regions() {
      // load all existing annotations into canvas_regions
      const regions = this.img_metadata[this.image_id].regions
      // console.log('当前选择的图片id：', this.image_id)
      this.canvas_regions = []
      for (let i = 0; i < regions.length; ++i) {
        const regioni = new ImageRegion()
        regioni.node_id = regions[i].node_id
        for (const key of regions[i].shape_attributes.keys()) { // img_metadata.regions存着该图片各个框的坐标信息
          const value = regions[i].shape_attributes.get(key)
          regioni.shape_attributes.set(key, value)
        }
        this.canvas_regions.push(regioni)
        switch (this.canvas_regions[i].shape_attributes.get('name')) {
          case this.REGION_SHAPE.RECT:
            const x = regions[i].shape_attributes.get('x') / this.canvas_scale // 转化为画布大小
            const y = regions[i].shape_attributes.get('y') / this.canvas_scale
            const width = regions[i].shape_attributes.get('width') / this.canvas_scale
            const height = regions[i].shape_attributes.get('height') / this.canvas_scale
            this.canvas_regions[i].shape_attributes.set('x', Math.round(x))
            this.canvas_regions[i].shape_attributes.set('y', Math.round(y))
            this.canvas_regions[i].shape_attributes.set('width', Math.round(width))
            this.canvas_regions[i].shape_attributes.set('height', Math.round(height))
            break
        }
      }
    },
    redraw_reg_canvas() {
      if (this.current_image_loaded) {
        if (this.canvas_regions.length > 0) {
          // 清空矩形框的画布
          this.reg_ctx.clearRect(0, 0, this.reg_canvas.width, this.reg_canvas.height)
          if (this.is_region_boundary_visible) { // 画画
            this.draw_all_regions()
          }
        }
      }
    },
    draw_all_regions() {
      for (let i = 0; i < this.canvas_regions.length; ++i) {
        const attr = this.canvas_regions[i].shape_attributes // canvas_regions存的是缩放过的
        const is_selected = this.canvas_regions[i].is_user_selected
        switch (attr.get('name')) {
          case this.REGION_SHAPE.RECT:
            this.draw_rect_region(attr.get('x'),
              attr.get('y'),
              attr.get('width'),
              attr.get('height'),
              attr.get('degree'),
              is_selected)
            break
        }
      }
    },
    draw_rect_region(x, y, w, h, degree, is_selected) {
      if (is_selected) {
        let t = this.draw_rect(x, y, w, h, degree)
        let new_x = t.new_x  //转换后的新坐标
        let new_y = t.new_y
        this.reg_ctx.strokeStyle = this.THEME_SEL_REGION_FILL_BOUNDARY_COLOR
        this.reg_ctx.lineWidth = this.THEME_REGION_BOUNDARY_WIDTH / 2
        this.reg_ctx.stroke() //绘制出通过 moveTo() 和 lineTo() 方法定义的路径
        this.reg_ctx.fillStyle = this.THEME_SEL_REGION_FILL_COLOR
        this.reg_ctx.globalAlpha = this.THEME_SEL_REGION_OPACITY //透明度
        this.reg_ctx.fill()
        this.reg_ctx.globalAlpha = 1.0  //不透明
        //画边角四个点
        this.draw_control_point(new_x[0], new_y[0])
        this.draw_control_point(new_x[1], new_y[1])
        this.draw_control_point(new_x[2], new_y[2])
        this.draw_control_point(new_x[3], new_y[3])
      } else {
        // draw a fill line
        this.reg_ctx.strokeStyle = this.THEME_BOUNDARY_FILL_COLOR
        this.reg_ctx.lineWidth = this.THEME_REGION_BOUNDARY_WIDTH
        // this.reg_ctx.lineWidth = this.THEME_REGION_BOUNDARY_WIDTH / 2
        this.draw_rect(x, y, w, h, degree)
        this.reg_ctx.stroke()
        // if (w > this.THEME_REGION_BOUNDARY_WIDTH &&
        //   h > this.THEME_REGION_BOUNDARY_WIDTH) {
        //   // draw a boundary line on both sides of the fill line
        //   this.reg_ctx.strokeStyle = this.THEME_BOUNDARY_LINE_COLOR
        //   this.reg_ctx.lineWidth = this.THEME_REGION_BOUNDARY_WIDTH / 4
        //   //花两条线
        //   this.draw_rect(x - this.THEME_REGION_BOUNDARY_WIDTH / 2,
        //     y - this.THEME_REGION_BOUNDARY_WIDTH / 2,
        //     w + this.THEME_REGION_BOUNDARY_WIDTH,
        //     h + this.THEME_REGION_BOUNDARY_WIDTH)
        //   this.reg_ctx.stroke()
        //   this.draw_rect(x + this.THEME_REGION_BOUNDARY_WIDTH / 2,
        //     y + this.THEME_REGION_BOUNDARY_WIDTH / 2,
        //     w - this.THEME_REGION_BOUNDARY_WIDTH,
        //     h - this.THEME_REGION_BOUNDARY_WIDTH)
        //   this.reg_ctx.stroke()
        // }
      }
    },
    // control point for resize of region boundaries
    draw_control_point(cx, cy) {
      this.reg_ctx.beginPath()
      this.reg_ctx.arc(cx, cy, this.REGION_POINT_RADIUS, 0, 2 * Math.PI, false)
      this.reg_ctx.closePath()
      this.reg_ctx.fillStyle = this.THEME_CONTROL_POINT_COLOR
      this.reg_ctx.globalAlpha = 1.0
      this.reg_ctx.fill()
    },
    draw_rect(x, y, w, h, degree) {
      if (degree === 0) {
        this.reg_ctx.beginPath()
        this.reg_ctx.moveTo(x, y)
        this.reg_ctx.lineTo(x + w, y)
        this.reg_ctx.lineTo(x + w, y + h)
        this.reg_ctx.lineTo(x, y + h)
        this.reg_ctx.closePath()//闭环,从当前点到开始点的路径
        let new_x = [x, x + w, x + w, x]
        let new_y = [y, y, y + h, y + h]
        return {
          new_x: new_x,
          new_y: new_y
        }
      } else {
        let c_x = x + w / 2
        let c_y = y + h / 2
        let t = this.compulte_new_xy(x, y, w, h, degree, c_x, c_y)
        let new_x = t.new_x
        let new_y = t.new_y
        this.reg_ctx.beginPath()
        this.reg_ctx.moveTo(new_x[0], new_y[0])
        this.reg_ctx.lineTo(new_x[1], new_y[1])
        this.reg_ctx.lineTo(new_x[2], new_y[2])
        this.reg_ctx.lineTo(new_x[3], new_y[3])
        this.reg_ctx.closePath()//闭环,从当前点到开始点的路径
        return {
          new_x: new_x,
          new_y: new_y
        }
      }
    },
    zoom_in() { // 放大
      if (!this.current_image_loaded) {
        // console.log('请先加载图片,First load some images!')
        return
      }
      if (this.canvas_zoom_level_index === (this.CANVAS_ZOOM_LEVELS.length - 1)) {
        // console.log('Further zoom-in not possible')
      } else {
        this.canvas_zoom_level_index += 1
        this.is_canvas_zoomed = true
        const zoom_scale = this.CANVAS_ZOOM_LEVELS[this.canvas_zoom_level_index]
        this.set_all_canvas_scale(zoom_scale)
        this.set_all_canvas_size(this.canvas_width * zoom_scale,
          this.canvas_height * zoom_scale)
        this.canvas_scale = this.canvas_scale_without_zoom / zoom_scale

        this.load_canvas_regions() // image to canvas space transform
        this.redraw_img_canvas()
        this.redraw_reg_canvas()
        this.reg_canvas.focus()
        // console.log('Zoomed in to level ' + zoom_scale + 'X')
      }
    },
    zoom_out() { // 缩小
      if (!this.current_image_loaded) {
        // console.log('请先加载图片,First load some images!')
        return
      }
      if (this.canvas_zoom_level_index === 0) { // 不能再缩小了
        // console.log('Further zoom-out not possible')
      } else {
        this.canvas_zoom_level_index -= 1
        this.is_canvas_zoomed = true
        const zoom_scale = this.CANVAS_ZOOM_LEVELS[this.canvas_zoom_level_index]
        this.set_all_canvas_scale(zoom_scale)
        this.set_all_canvas_size(this.canvas_width * zoom_scale,
          this.canvas_height * zoom_scale) // 缩放画布，但是会把图片清空
        this.canvas_scale = this.canvas_scale_without_zoom / zoom_scale

        this.load_canvas_regions() // 加载当前图片的标注框image to canvas space transform
        this.redraw_img_canvas() // 画图片
        this.redraw_reg_canvas() // 画矩形框
        this.reg_canvas.focus()
        // console.log('Zoomed out to level ' + zoom_scale + 'X')
      }
    },
    reset_zoom_level() {
      if (!this.current_image_loaded) {
        // console.log('First load some images!')
        return
      }
      if (this.is_canvas_zoomed) {
        this.is_canvas_zoomed = false
        this.canvas_zoom_level_index = this.CANVAS_DEFAULT_ZOOM_LEVEL_INDEX
        const zoom_scale = this.CANVAS_ZOOM_LEVELS[this.canvas_zoom_level_index]
        this.set_all_canvas_scale(zoom_scale)
        this.set_all_canvas_size(this.canvas_width, this.canvas_height)
        this.canvas_scale = this.canvas_scale_without_zoom

        this.load_canvas_regions() // image to canvas space transform
        this.redraw_img_canvas()
        this.redraw_reg_canvas()
        this.reg_canvas.focus()
        // console.log('Zoom reset')
      } else {
        // console.log('Cannot reset zoom because image zoom has not been applied!')
      }
    },
    redraw_img_canvas() {
      if (this.current_image_loaded) {
        this.img_ctx.clearRect(0, 0, this.img_canvas.width, this.img_canvas.height)
        this.img_ctx.drawImage(this.current_image, 0, 0,
          this.img_canvas.width, this.img_canvas.height)
      }
    },
    is_on_region_corner(px, py) {
      const region_edge = [-1, -1] // region_id, corner_id [top-left=1,top-right=2,bottom-right=3,bottom-left=4]
      for (let i = 0; i < this.canvas_regions.length; ++i) { // canvas_regions存着当前图片的框坐标，非原图尺度
        const attr = this.canvas_regions[i].shape_attributes
        let result = false
        region_edge[0] = i
        switch (attr.get('name')) {
          case this.REGION_SHAPE.RECT:
            result = this.is_on_rect_edge(attr.get('x'),
              attr.get('y'),
              attr.get('width'),
              attr.get('height'),
              attr.get('degree'),
              px, py)
            break
        }
        if (result > 0) { // 电机在框i的边缘上
          region_edge[1] = result
          return region_edge
        }
      }
      region_edge[0] = -1
      return region_edge
    },
    is_on_rect_edge(x, y, w, h, degree, px, py) {
      if (degree === 0) {
        let dx0 = Math.abs(x - px)
        let dy0 = Math.abs(y - py)
        let dx1 = Math.abs(x + w - px)
        let dy1 = Math.abs(y + h - py)
        //[top-left=1,top-right=2,bottom-right=3,bottom-left=4]
        if (dx0 < this.REGION_EDGE_TOL &&
          dy0 < this.REGION_EDGE_TOL) {
          return 1
        }
        if (dx1 < this.REGION_EDGE_TOL &&
          dy0 < this.REGION_EDGE_TOL) {
          return 2
        }
        if (dx1 < this.REGION_EDGE_TOL &&
          dy1 < this.REGION_EDGE_TOL) {
          return 3
        }
        if (dx0 < this.REGION_EDGE_TOL &&
          dy1 < this.REGION_EDGE_TOL) {
          return 4
        }
        return 0
      } else {
        let c_x = x + w / 2
        let c_y = y + h / 2
        let t = this.compulte_new_xy(x, y, w, h, degree, c_x, c_y)
        let new_x = t.new_x
        let new_y = t.new_y
        for (let i = 0; i < new_x.length; i++) {
          let dx = Math.abs(new_x[i] - px)
          let dy = Math.abs(new_y[i] - py)
          if (dx < this.REGION_EDGE_TOL &&
            dy < this.REGION_EDGE_TOL) {
            return i + 1
          }
        }
        return 0
      }
    },
    is_inside_region(px, py, descending_order) {
      const N = this.canvas_regions.length
      if (N === 0) {
        return -1
      }
      let start, end, del
      // traverse the canvas regions in alternating ascending
      // and descending order to solve the issue of nested regions
      if (descending_order) {
        start = N - 1
        end = -1
        del = -1
      } else {
        start = 0
        end = N
        del = 1
      }
      let i = start
      while (i !== end) {
        const yes = this.is_inside_this_region(px, py, i)
        if (yes) {
          return i
        }
        i = i + del
      }
      return -1
    },
    is_inside_this_region(px, py, region_id) {
      const attr = this.canvas_regions[region_id].shape_attributes
      let result = false
      switch (attr.get('name')) {
        case this.REGION_SHAPE.RECT:
          result = this.is_inside_rect(attr.get('x'),
            attr.get('y'),
            attr.get('width'),
            attr.get('height'),
            attr.get('degree'),
            px, py)
          break
      }
      return result
    },
    is_inside_rect(x, y, w, h, degree, px, py) {
      if (degree === 0) {
        return px > x &&
          px < (x + w) &&
          py > y &&
          py < (y + h)
      } else {
        let c_x = x + w / 2  //旋转中心
        let c_y = y + h / 2
        let t = this.compulte_new_xy(x, y, w, h, degree, c_x, c_y)  //绕着矩形中心旋转degree度
        let all_points_x = t.new_x
        let all_points_y = t.new_y
        all_points_x.push(t.new_x[0])  //形成一个闭环
        all_points_y.push(t.new_y[0])
        let wn = 0    // the  winding number counter
        // loop through all edges of the polygon
        for (let i = 0; i < all_points_x.length - 1; i++) {   // edge from V[i] to  V[i+1]
          let is_left_value = this.is_left(all_points_x[i], all_points_y[i],
            all_points_x[i + 1], all_points_y[i + 1],
            px, py)
          if (all_points_y[i] <= py) {
            if (all_points_y[i + 1] > py && is_left_value > 0) {  // 线是从下到上,点击点在线的左边
              ++wn
            }
          } else {
            if (all_points_y[i + 1] <= py && is_left_value < 0) {  //线是从上到下,点击点在线的右边
              --wn
            }
          }
        }
        return wn !== 0
      }
    },
    // returns
    // >0 if (x2,y2) lies on the left side of line joining (x0,y0) and (x1,y1)
    // =0 if (x2,y2) lies on the line joining (x0,y0) and (x1,y1)
    // >0 if (x2,y2) lies on the right side of line joining (x0,y0) and (x1,y1)
    // source: http://geomalgorithms.com/a03-_inclusion.html
    is_left(x0, y0, x1, y1, x2, y2) {
      return (((x1 - x0) * (y2 - y0)) - ((x2 - x0) * (y1 - y0)))
    },
    toggle_all_regions_selection(is_selected) {
      for (let i = 0; i < this.canvas_regions.length; ++i) {
        this.canvas_regions[i].is_user_selected = is_selected // 当前图片的所有region都清空
        this.img_metadata[this.image_id].regions[i].is_user_selected = is_selected
      }
      this.is_all_region_selected = is_selected
    },
    rect_update_corner(corner_id, d, x, y) {
      // pre-condition : d[x0,y0,x1,y1] is standarized
      // post-condition : corner is moved ( d may not stay standarized )
      switch (corner_id) {
        case 1: // top-left
          d[0] = x
          d[1] = y
          break
        case 3: // bottom-right
          d[2] = x
          d[3] = y
          break
        case 2: // top-right
          d[2] = x
          d[1] = y
          break
        case 4: // bottom-left
          d[0] = x
          d[3] = y
          break
      }
    },
    rect_standarize_coordinates(d) {
      // d[x0,y0,x1,y1]
      // ensures that (d[0],d[1]) is top-left corner while
      // (d[2],d[3]) is bottom-right corner
      if (d[0] > d[2]) {
        // swap
        const t = d[0]
        d[0] = d[2]
        d[2] = t
      }

      if (d[1] > d[3]) {
        // swap
        const t = d[1]
        d[1] = d[3]
        d[3] = t
      }
    },
    set_region_select_state(region_id, is_selected) {
      this.canvas_regions[region_id].is_user_selected = is_selected
      this.img_metadata[this.image_id].regions[region_id].is_user_selected = is_selected
    },
    clear_reg_canvas() {
      this.reg_ctx.clearRect(0, 0, this.reg_canvas.width, this.reg_canvas.height)
    },
    // 远程文件资源管理器的函数
    getResource() {
      this.isDialogOpen = true
      // console.log(this.$store.state.marking.flag)
      // this.$store.commit('OPEN_DIALOG')
      // this.selectpath = ''
      this.centerDialogVisible = true
      this.explorerInit()
      this.getData(this.selectpath)
    },
    getData(filepath) {
      let i = Date.parse(new Date())
      getFiles(filepath).then((res) => {
        console.log('返回成功，结果：', res)
        if (res.data.status === 1) {
          this.dataArr = []
          const folderFiles = res.data.allList
          // console.log('123')
          // console.log(res.data.allList)
          /*
          filename: "jpg1"
          filepath: "/home/fzuir/newspaper_data/jpg1"
          type: "folder"
          */
          for (const item of folderFiles) {
            // // console.log(item)
            const data_item = {}
            data_item['key'] = i++
            data_item['name'] = item.filename
            data_item['filepath'] = item.filepath
            data_item['type'] = item.type
            if (item.type === 'image') {
              data_item['height'] = item.height
              data_item['size'] = item.size
              data_item['width'] = item.width
              // data_item['base64'] = item.base64
            }
            this.dataArr.push(data_item)
          }
          // console.log('dataArr:', this.dataArr)
          this.currentPath = filepath // 获取filepath下的文件夹后，把当前路径设置为filepath
          this.selectpath = filepath
        } else {
          this.openMessageBox('路径不存在')
          // console.log('11111111', this.dataArr)
        }
      }).catch((error) => {
        // console.log('fileSel与后端通讯发生错误', error)
      })
    },
    clickFolder(item) {
      // console.log('clickFolder', item)
    },
    clickFile(item) {
      // console.log('clickFile', item)
    },
    dblclickFolder(event) {
      // console.log('双击文件夹，进入别的文件夹，需要将当前路径记录在栈里')
      this.pathStack.push(this.currentPath)
      const folderPath = event['filepath']
      // console.log('pathStack:', this.pathStack)
      this.explorerInit()
      if (event['type'] === 'folder') {
        this.getData(folderPath)
      }
    },
    dblclickFile() {
      // console.log('dblclickFile')
    },
    getBack() {
      // console.log('返回上一级')
      const i = this.pathStack.length
      if (i >= 1) {
        this.explorerInit()
        const backPath = this.pathStack[i - 1] // 取栈顶元素
        this.pathStack.pop()
        // console.log('返回上一级路径', backPath)
        this.getData(backPath)
      } else {
        this.openMessageBox('没有上一级了！')
      }
    },
    openMessageBox(message) {
      this.$alert(message, ' ', {
        confirmButtonText: '确定'
        // callback: action => {
        //   this.$message({
        //     type: 'info',
        //     message: `action: ${ action }`
        //   });
        // }
      })
    },
    dragMove(folder, data) {
      // console.log(folder, data)
    },
    explorerInit() {
      this.selectedArr.splice(0, this.selectedArr.length)
      this.dataArr.splice(0, this.dataArr.length)
      this.selection = true
      this.seletedFileList.splice(0, this.seletedFileList.length)
    },

    sumbitData() {
      this.isDialogOpen = false
      // this.$store.commit('CLOSE_DIALOG')
      this.centerDialogVisible = false
      // console.log('sumbit')
      this.seletedFileList.splice(0, this.seletedFileList.length)
      if (this.selectedArr.length !== 0) {
        for (const one of this.selectedArr) {
          this.seletedFileList.push(one)
        }
        // console.log(this.seletedFileList)  //选择的文件列表
      }
      this.store_remote_img_ref()
    },
    // 远程文件选择
    store_remote_img_ref() {
      const user_selected_images = this.seletedFileList // 选中的文件
      const original_image_count = this.img_count // 已经选的文件数量
      if (original_image_count === 0) {
        localStorage.clear()
      }
      let discarded_file_count = 0
      for (let i = 0; i < user_selected_images.length; ++i) { // 遍历选好的图片
        const filetype = user_selected_images[i].type // 获得已选中文件的类型
        // // console.log('filetype:', filetype);
        if (filetype === 'image') {
          const filename = user_selected_images[i].name
          const filepath = user_selected_images[i].filepath
          const size = user_selected_images[i].size
          const result_path = user_selected_images[i].result_path
          const filestatus = user_selected_images[i].status
          const img_id = user_selected_images[i].key //用数据库的image_id作为图片的索引
          // // console.log('img_metadata:', this.img_metadata)
          if (this.img_metadata.hasOwnProperty(img_id)) { // 如果img_metadata里面已经存这张图片了
            if (this.img_metadata[img_id].fileref) { // image的详细信息,名字，大小，type等
              // console.log('已经加载过该图片', filename)
            } else {
              this.img_metadata[img_id].fileref = user_selected_images[i]
            }
          } else { // 新建图片
            // console.log('imglist没有这张图片，新建图片信息存入img_metadata')
            this.img_metadata[img_id] = new ImageMetadata(user_selected_images[i], filename, size, img_id, result_path)
            // let imgDetail = {}
            // imgDetail.imageName = filename
            // imgDetail.status = filestatus
            let image_info = {
              id: img_id,
              name: {
                imageName: filename,
                status: filestatus
              },
              path: filepath
            }
            this.image_info_list.push(image_info)
            // this.image_id_list.push(img_id)
            // this.image_name_list.push(imgDetail)
            // // this.image_name_list.push(filename)
            // this.image_path_list.push(filepath)
            this.img_count += 1 // 已经加载的图片数量++
          }
        } else { // 选择了非图片
          discarded_file_count += 1
        }
      }
      this.image_info_list.sort(this.compare_image)
    },
    show_remote_image(image_index) { // 展示图片 image_index:图片列表的index
      this.reposition()
      this.currentIndex = image_index
      console.log('将要展示的图片在列表中的index:', image_index)
      if (this.is_loading_current_image) {
        this.$notify({
          title: '请等当前图片加载完再点击',
          type: 'warning',
          duration: 1500
        })
        return
      }
      const img_id = this.image_info_list[image_index].id // 新的image_id
      if (!this.img_metadata.hasOwnProperty(img_id)) {
        console.log('无法找到此图片id:', img_id)
        return
      }
      const img_filename = this.img_metadata[img_id].filename
      const local_node_data = this.img_metadata[img_id].node_tree
      const local_is_vetical = this.img_metadata[img_id].isVetical
      const result_path = this.img_metadata[img_id].result_path
      const img_reader = new FileReader()
      this.is_loading_current_image = true // 正在加载图片
      const that = this
      img_reader.addEventListener('loadstart', function(e) {
      }, false)
      img_reader.addEventListener('progress', function(e) {
      }, false)
      img_reader.addEventListener('error', function() {
        that.is_loading_current_image = false
        // console.log('加载图片出错' + img_filename + ' !')
      }, false)
      img_reader.addEventListener('abort', function() {
        that.is_loading_current_image = false
        // console.log('Aborted loading image ' + img_filename + ' !')
      }, false)
      img_reader.addEventListener('load', function() {
        // // console.log('1234345436')
        that.current_image = new Image()
        that.current_image.addEventListener('error', function() {
          that.is_loading_current_image = false
          console.log('Error loading image ' + img_filename + ' !')
        }, false)
        that.current_image.addEventListener('abort', function() {
          that.is_loading_current_image = false
          console.log('Aborted loading image ' + img_filename + ' !')
        }, false)
        that.current_image.addEventListener('load', function() {
          // update the current state of application
          that.image_id = img_id // 当前的图片id
          that.image_index = image_index // 当前的图片在img_list中的索引
          that.current_image_filename = img_filename
          that.current_image_loaded = true // 图片加载成功
          that.is_loading_current_image = false // 目前不在加载图片
          that.result_path = result_path
          that.click_x0 = 0 // 画框的时候用来记录点
          that.click_y0 = 0
          that.click_x1 = 0
          that.click_y1 = 0
          that.is_user_drawing_region = false
          that.is_window_resized = false
          that.is_user_resizing_region = false
          that.is_user_moving_region = false
          that.is_user_drawing_polygon = false
          that.is_region_selected = false
          that.user_sel_region_id = -1
          that.current_image_width = that.current_image.naturalWidth // 图片真实的宽高
          that.current_image_height = that.current_image.naturalHeight
          // // console.log('that.current_image', that.current_image)
          // console.log('that.current_image_width', that.current_image_width)
          // console.log('that.current_image_height', that.current_image_height)
          // set the size of canvas
          // based on the current dimension of browser window
          const de = document.documentElement
          const canvas_panel_width = de.clientWidth - 230 // 宽度-侧边栏的宽度 页面用于显示图像部分的宽高
          const canvas_panel_height = de.clientHeight - 2 * that.ui_top_panel.offsetHeight// 高度-2倍顶栏
          that.canvas_width = that.current_image_width // 真实图片宽度
          that.canvas_height = that.current_image_height
          if (that.canvas_width > canvas_panel_width) { // 如果原图像的大小>页面用于显示图片区域的大小
            // resize image to match the panel width
            const scale_width = canvas_panel_width / that.current_image.naturalWidth
            that.canvas_width = canvas_panel_width // resize
            that.canvas_height = that.current_image.naturalHeight * scale_width
          }
          if (that.canvas_height > canvas_panel_height) {
            // resize further image if its height is larger than the image panel
            const scale_height = canvas_panel_height / that.canvas_height
            that.canvas_height = canvas_panel_height
            that.canvas_width = that.canvas_width * scale_height
          }
          that.canvas_width = Math.round(that.canvas_width)
          that.canvas_height = Math.round(that.canvas_height)
          that.canvas_scale = that.current_image.naturalWidth / that.canvas_width
          that.canvas_scale_without_zoom = that.canvas_scale // 缩放比例
          that.set_all_canvas_size(that.canvas_width, that.canvas_height) // resize img_region和cav_region

          // we only need to draw the image once in the image_canvas 在image_canvas上画一次原图
          that.img_ctx.clearRect(0, 0, that.canvas_width, that.canvas_height) // 清空一定区域内的像素
          that.img_ctx.drawImage(that.current_image, 0, 0, that.canvas_width, that.canvas_height)

          // 加载目录树，如果本地该图片的目录树不为空，则加载本地
          // 如果本地为空，远程端目录树不为'none'，则加载远程的node_data和is_vetical
          that.max_id = 0 // 每一张图片都有自己的从0开始的id编号，由于可能会删除区域，所以不可能连续，所以要获得最大的id，方便接下来计数
          if (local_node_data.length !== 0) {
            // console.log('加载本地目录树数据')
            that.isVetical = local_is_vetical // 加载本地该图片的isVetical信息
            // console.log('本地的isVetical', that.isVetical)
            that.node_data = local_node_data // 加载本地目录树，由于加载本地，所以本地的region已经存了所有的信息了
            for (let i = 0; i < that.node_data.length; i++) { // 获取该目录树的最大id
              that.get_max_id(that.node_data[i])
            }
          } else {
            if (that.remote_node_data !== 'none') {
              // console.log('加载远程目录树数据')
              that.node_data = that.remote_node_data // 加载远程的目录树信息
              that.isVetical = that.remote_is_vetical // 加载远程端的is_vetical信息
              // 把远程端的目录树信息写入that.img_metadata[img_id].
              that.remote_regions = []
              for (let i = 0; i < that.node_data.length; i++) {
                that.load_remote_data(that.node_data[i]) // 把node_data写入regions
                that.get_max_id(that.node_data[i]) // 获取目录树当前最大id
              }
              that.img_metadata[img_id].node_tree = that.remote_node_data
              that.img_metadata[img_id].isVetical = that.isVetical
              that.img_metadata[img_id].regions = that.remote_regions
            } else {
              // console.log('本地和远程该目录树都为空')
              that.node_data = local_node_data
              that.isVetical = local_is_vetical
            }
          }
          // console.log('当前node_data的最大id', that.max_id)
          that.nid = that.max_id + 1 // 用来计数
          // console.log('img_metadata', that.img_metadata[img_id])
          that.load_canvas_regions() // 将img_meta中的regions加载到canvas层面
          that.redraw_reg_canvas()
          that.reg_canvas.focus() // 焦点设置在regcav上，以便画图
        })
        // // console.log('img_reader.result', img_reader.result)
        that.current_image.src = img_reader.result
      }, false)
      new Promise((resolve, reject) => {
        resolve(getImageInfo(that.img_metadata[img_id].fileref.filepath, that.img_metadata[img_id].result_path))// 请求img的地址
      }).then((res) => {
        that.img_metadata[img_id].base64_img_data = res.data.imageBase64
        that.remote_node_data = res.data.node_data // 获取远程的nodedata，如果为'none',则说明远程端没有该文件的标注数据
        console.log('res.data.node_data:' + res.data.node_data)
        that.remote_is_vetical = res.data.is_vetical // 获取远程的is_vetical状态
        if (that.img_metadata[img_id].base64_img_data === '') {
          // load image from file
          img_reader.readAsDataURL(that.img_metadata[img_id].fileref)
        } else {
          // load image from base64 data or URL
          img_reader.readAsText(new Blob([that.img_metadata[img_id].base64_img_data]))
        }
      })
    },
    compare_image(a, b) {
      if (this.statusOrder[a.name.status.toString()] < this.statusOrder[b.name.status.toString()]) {
        return -1  //当a的状态排序比b的小的时候，排在前面
      } else if (this.statusOrder[a.name.status.toString()] > this.statusOrder[b.name.status.toString()]) {
        return 1 //当a的状态排序比b的大的时候，排在后面
      } else { //如果状态相同，则根据文件名排序
        if (a.name.imageName < b.name.imageName) {
          return -1
        } else if (a.name.imageName > b.name.imageName) {
          return 1
        } else {
          return 0
        }
      }
    },
    compulte_new_xy(x, y, w, h, degree, c_x, c_y) {
      let old_x = [x, x + w, x + w, x]
      let old_y = [y, y, y + h, y + h]
      let new_x = []
      let new_y = []
      for (let i = 0; i < old_x.length; i++) {  //矩形四角绕中心点旋转degree度
        new_x.push(Math.round((old_x[i] - c_x) * Math.cos(degree * (Math.PI / 180)) - (old_y[i] - c_y) * Math.sin(degree * (Math.PI / 180)) + c_x))
        new_y.push(Math.round((old_x[i] - c_x) * Math.sin(degree * (Math.PI / 180)) + (old_y[i] - c_y) * Math.cos(degree * (Math.PI / 180)) + c_y))
      }
      return {
        new_x: new_x,
        new_y: new_y
      }
    },
    get_max_id(n_data) { // 获得目录树的最大id值
      if (n_data['id'] > this.max_id) {
        this.max_id = n_data['id']
      }
      for (let i = 0; i < n_data['children'].length; i++) {
        this.get_max_id(n_data['children'][i])
      }
    },
    load_remote_data(n_data) { // 遍历加载regions
      // // console.log('child', n_data['children'])
      if (n_data['xy'].length !== 0) {
        const x = Math.round(n_data['xy'][0]) // 实际坐标
        const y = Math.round(n_data['xy'][1])
        const width = Math.round(n_data['xy'][2] - n_data['xy'][0])
        const height = Math.round(n_data['xy'][3] - n_data['xy'][1])
        let degree = 0
        if (n_data.hasOwnProperty('degree')) {
          degree = n_data['degree']  //倾斜角(非弧度)，倾斜角不为0的时候，xy的坐标经过倾斜角转换才是真实框的坐标
        } else {
          n_data['degree'] = 0
        }
        const img_region = new ImageRegion()
        img_region.node_id = n_data['id']
        img_region.shape_attributes.set('name', 'rect')
        img_region.shape_attributes.set('degree', degree)  //角度而非弧度
        img_region.shape_attributes.set('x', x)
        img_region.shape_attributes.set('y', y)
        img_region.shape_attributes.set('width', width)
        img_region.shape_attributes.set('height', height)
        this.remote_regions.push(img_region)
      }
      for (let i = 0; i < n_data['children'].length; i++) {
        this.load_remote_data(n_data['children'][i])
      }
    },
    selectFiles() {
      this.getData(this.selectpath)
      this.pathStack.push(this.currentPath)
    },
    go_back() {
      // this.$router.push({
      //   path: 'taskMark'
      // })
      // this.$store.dispatch('taskcheck', this.$route);
      this.$router.replace('taskMark')
      // this.$router.go(-1);
    },
    closeDialog() {
      this.centerDialogVisible = false
      this.isDialogOpen = false
      // this.$store.commit('CLOSE_DIALOG')
    },
    submitSuccessNotify() {
      this.$notify({
        title: '上传成功',
        type: 'success',
        duration: 2500
      })
    },
    submitFailureNotify(error) {
      this.$notify({
        title: '上传失败' + error,
        type: 'error',
        duration: 2500
      })
    },
    changeVetical() {
      const img_id = this.image_info_list[this.image_index].id
      // console.log('this.isVetical', this.isVetical)
      this.img_metadata[img_id].isVetical = this.isVetical // 修改排版状态
      // console.log(this.img_metadata[img_id])
    }
  }
}

</script>

<style scoped>
body {
  min-width: 800px;
  padding: 0;
  margin: 0;
  font-family: "Microsoft YaHei";
}

body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, table, th, td {
  margin: 0;
  padding: 0;
}

.top_panel {
  position: fixed;
  display: block;
  font-size: medium;
  background-color: #42b983;
  color: whitesmoke;
  z-index: 10;
  margin: 0;
  padding: 0;
  width: 100%;
}

.navbar {
  display: right;
}

.navbar ul {
  display: inline;
  list-style-type: none;
  overflow: hidden;
}

.navbar li {
  float: left;
}

.navbar li a, .drop_menu_item {
  display: inline-block;
  color: whitesmoke;
  padding: 0.65em 1.2em;
  text-decoration: none;
}

.navbar li a:hover, .dropdown:hover {
  background-color: #42b983;
  cursor: pointer;
}

.navbar li.dropdown {
  display: inline-block;
}

.navbar .dropdown-content {
  display: none;
  position: absolute;
  background-color: #42b983;
  min-width: 120px;
  border: 1px solid #ffffff;
  font-size: small;
}

.navbar .dropdown-content a {
  color: whitesmoke;
  padding: 0.4em 0.6em;
  text-decoration: none;
  display: block;
  text-align: left;
  background-color: #42b983;
  float: none;
}

.navbar .dropdown-content a:hover {
  background-color: #FFC000;
  color: whitesmoke;
}

.navbar .dropdown:hover .dropdown-content {
  display: block;
}

.toolbar {
  display: inline-block;
  color: white;
  vertical-align: top;
}

.toolbar ul {
  display: inline;
  list-style-type: none;
  overflow: hidden;
}

.toolbar li {
  font-size: medium;
  float: left;
  padding: 0.65em 0.3em;
  color: whitesmoke;
}

.toolbar li:hover {
  background-color: #FFC000;
  color: black;
  cursor: pointer;
}

#fileinfo {
  font-size: small;
  padding: 1.2em 0.8em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Middle panel: containing #image_panel, #leftsidebar */
.middle_panel {
  position: relative;
  display: table;
  table-layout: fixed;
  width: 100%;
  z-index: 1;
  padding: 0;
  top: 3.5em;
  /*padding-top: 1.0125em;  ensures the mouse event (x,y) coordinates are integer */
}

#leftsidebar {
  display: table-cell;
  width: 250px;
  z-index: 10;
  vertical-align: top;
}

#display_area {
  display: table-cell;
  width: 100%;
  z-index: 1;
  margin: 0;
  padding-left: 1em;
  vertical-align: top;
}

#canvas_panel {
  position: relative;
  margin: 0;
  padding: 0;
}

#leftsidebar_collapse_panel {
  display: table-cell;
  position: relative;
  width: 10px;
  z-index: 1;
  vertical-align: top;
  font-size: small;
}

#leftsidebar_collapse_button {
  background-color: #42b983;
  width: 10px;
  height: 25px;
  color: whitesmoke;
  padding: 0.2em;
  border-radius: 0px 5px 5px 0px;
  font-size: large;
}

#leftsidebar_collapse_button:hover {
  color: white;
  cursor: pointer;
}

/* Left sidebar accordion */
button.leftsidebar_accordion {
  font-size: large;
  background-color: #f2f2f2;
  cursor: pointer;
  padding: 0.5em 0.5em;
  width: 100%;
  text-align: left;
  border: 0;
  outline: none;
}

button.leftsidebar_accordion:focus {
  outline: none;
}

button.leftsidebar_accordion.active, button.leftsidebar_accordion:hover {
  background-color: #e6e6e6;
}

button.leftsidebar_accordion:after {
  content: '\02795';
  color: #4d4d4d;
  float: right;
}

button.leftsidebar_accordion.active:after {
  content: '\2796';
}

.leftsidebar_accordion_panel {
  display: none;
  padding-top: 0;
  padding-left: 0.5em;
  font-size: small;
  border-right: 2px solid #f2f2f2;
  border-bottom: 2px solid #f2f2f2;
}

.leftsidebar_accordion_panel.show {
  display: block;
}

/* Region shape selection panel inside leftsidebar */
ul.region_shape {
  font-size: xx-large;
  list-style-type: none;
  overflow: hidden;
  padding: 0.4em 0;
  margin: 0;
}

ul.region_shape li {
  float: left;
  padding: 0 0.2em;
  fill: #ffffff;
  stroke: #000000;
}

ul.region_shape li:hover {
  cursor: pointer;
  fill: #ffffff;
  stroke: #ff0000;
}

ul.region_shape .selected {
  fill: #ffffff;
  stroke: #ff0000;
}

/* Loaded image list shown in leftsidebar panel */
#img_list_panel {
  display: none;
  height: 0;
  font-size: small;
  overflow: scroll;
}

#img_list_panel ul {
  position: relative;
  line-height: 1.3em;
  padding-left: 0;
  list-style-type: none;
}

#img_list_panel li {
  white-space: nowrap;
}

#img_list_panel li:hover {
  background-color: #cccccc;
  color: #000000;
  cursor: pointer;
}

#message_panel {
  position: fixed;
  left: 0;
  bottom: 0px;
  line-height: 3em;
  width: 100%;
  background-color: #00a9cf;
  color: black;
  font-size: small;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 1000;
}

#invisible_file_input {
  width: 0.1px;
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  z-index: -1;
}

.text_panel {
  display: none;
  margin: auto;
  font-size: medium;
  line-height: 1.3em;
  margin: 0;
  max-width: 700px;
}

.text_panel li {
  margin: 1em 0;
  text-align: left;
}

.text_panel p {
  text-align: left;
}

.action_text_link {
  background-color: #aaeeff;
  color: #000000;
}

.action_text_link:hover {
  cursor: pointer;
}

.svg_button:hover {
  cursor: pointer;
}

.tool_button {
  color: blue;
  cursor: pointer;
}

.tool_button:hover {
  color: red;
}

/* region and file attributes input panel (spreadsheet like) */
#attributes_panel {
  display: none;
  position: fixed;
  bottom: 0;
  z-index: 10;
  width: 100%;
  max-height: 30%;
  overflow: auto;
  background-color: #ffffff;
  border-top: 4px solid #000000;
  padding: 0em 0em;
  padding-bottom: 2em;
  font-size: small;
}

#attributes_panel table {
  border-collapse: collapse;
  table-layout: fixed;
  margin: 1em;
  margin-bottom: 2em;
}

#attributes_panel td {
  border: 1px solid #999999;
  padding: 1em 1em;
  margin: 0;
  height: 1em;
  white-space: nowrap;
  vertical-align: top;
}

#attributes_panel tr:first-child td, #attributes_panel td:first-child {
  padding: 1em 1em;
  text-align: center;
}

#attributes_panel input {
  border: none;
  padding: 0;
  margin: 0;
  display: table-cell;
  height: 1.3em;
  font-size: small;
  background-color: #ffffff;
  vertical-align: top;
}

#attributes_panel input:hover {
  background-color: #e6e6e6;
}

#attributes_panel input:focus {
  background-color: #e6e6e6;
}

#attributes_panel input:not(:focus) {
  text-align: center;
}

#attributes_panel textarea {
  border: none;
  padding: 0;
  margin: 0;
  display: table-cell;
  font-size: small;
  background-color: #ffffff;
}

#attributes_panel textarea:hover {
  background-color: #e6e6e6;
}

#attributes_panel textarea:focus {
  background-color: #e6e6e6;
}

#attributes_panel_toolbar {
  display: block;
  height: 30px;
  width: 100%;
  position: relative;
  padding: 0;
  margin: 0;
}

.attributes_panel_button {
  width: 10px;
  color: black;
  font-size: x-large;
  margin-left: 0.5em;
  padding: 0;
}

.attributes_panel_button:hover {
  color: red;
  cursor: pointer;
}

/* layers of canvas */
#image_panel {
  position: relative;
  display: inline-block;
  margin: auto;
  margin-top: 1em;
}

#image_canvas {
  position: absolute;
  border: 2px solid #d71b1b;
  top: 0px;
  left: 0px;
  z-index: 1;
}

#region_canvas {
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 2;
}

/* Loading spinbar */
.loading_spinbox {
  display: inline-block;
  border: 0.4em solid #cccccc;
  border-radius: 50%;
  border-top: 0.4em solid #000000;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
}

@-webkit-keyframes spin {
  0% {
    -webkit-transform: rotate(0deg);
  }

  100% {
    -webkit-transform: rotate(360deg);
  }
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.text {
  font-size: 14px;
}

li {
  list-style: none;
}

.item {
  margin-bottom: 18px;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}

.clearfix:after {
  clear: both
}

.box-card {
  width: auto;
  /*padding-left: 5px;*/
}

.el-dropdown-link {
  cursor: pointer;
  color: #409EFF;
}

.el-icon-arrow-down {
  font-size: 12px;
}

.demonstration {
  display: block;
  color: #8492a6;
  font-size: 14px;
  margin-bottom: 20px;
}

.custom-class .menu_item__available:hover {
  background: #ffecf2 !important;
  color: #ff4050 !important;
}

.leftSizeBar {
  position: fixed;
}

.box-card {
  height: 100%;
  /*padding: 0;*/
}

.tree_box {
  max-height: 400px;
  overflow: auto;
}

.box {
  max-height: 200px;
  overflow: auto;
}

.explorerBox {
  height: 390px;
  overflow: auto;
}

.el-switch__label {
  position: absolute;
  display: none;
  font-size: 11px !important;
  color: #fff !important;
}

.el-switch__label * {
  font-size: 11px !important;
}

/*打开时文字位置设置*/
.el-switch__label--right {
  z-index: 1;
  right: -10px;
  top: 0.5px;
}

/*关闭时文字位置设置*/
.el-switch__label--left {
  z-index: 1;
  left: 23px;
  top: 0.5px;
}

/*显示文字*/
.el-switch__label.is-active {
  display: block;
}

.el-switch__core {
  width: 45px;
  height: 22px;
  border: 2px solid #DCDFE6;
  border-radius: 13px;
}

.active {
  color: red;
}

.btnClass {
  font-size: 16px;
  margin-right: 30px;
  margin-left: 30px;
}

.mainSizeBar {
  margin-left: 250px;
}

/* >>> .el-tree-node:focus > .el-tree-node__content {
  background-color：rgb(3, 35, 68);
  } */
/* .warpper .el-tree--highlight-current >>> .el-tree-node.is-checked > .el-tree-node__content {
    background-color: rgb(255, 255, 255);
    color:rgb(64, 158, 255);
  }
 .warpper .el-tree--highlight-current >>> .el-tree-node.is-current > .el-tree-node__content {
    background-color: rgb(212, 107, 107);
    color:rgb(3, 35, 68);
  } */
</style>
